// auction_matching_kdtree.h
// 04/20/2011 : created
#pragma once
#include "geometric_problem.h"
#include "kdtree_template.h"

class KDTreePrice : public KDTreeTemplate<KDTreePrice>
{
  typedef KDTreeTemplate<KDTreePrice> __Base;
  typedef __Base::dataset_type        dataset_type;
protected:
  std::vector<double>& m_price;
  double m_minPrice, m_maxPrice;
public:
  KDTreePrice(dataset_type& data, std::vector<double>& price) : __Base(data), m_price(price) {}
  KDTreePrice(KDTreePrice* parent, int s, int e) : __Base(parent, s, e), m_price(parent->m_price) {}
  double implementKNN(const vec& query, std::vector<int>& knnIdx, std::vector<double>& minBound);
  double price(int i) const { return m_price[m_s+i]; }
  void set_price(int i, double price);
  void updatePrice();
  KDTreePrice* findLeaf(int idx);
};

class AuctionMatchingKDTree : public Matching
{
protected:
  KDTreePrice *m_refTree;
public:
  AuctionMatchingKDTree(const std::string& name = "Auction matching with kd-tree") : Matching(name), m_refTree(NULL) {}
  void loadData(const std::string& fName1, const std::string& fName2) {
    Matching::loadData(fName1, fName2);
    if (m_refTree) {
      delete m_refTree;
      m_refTree = NULL;
    }
  }
  void solve();
};

class KDTreePriceBuild : public Problem
{
  std::vector<vec> m_point;
  KDTreePrice *m_tree;
public:
  KDTreePriceBuild(const std::string& name = "Build KDTreePrice") : Problem(name), m_tree(NULL) {}
  void loadData(const std::string& fName);
  void solve();
  void draw(Plotter& pl);
  KDTreePrice* tree() const { return m_tree; }
};
